/*
 * Copyright (C) 2009 Show SMS open source project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.bydavy.android.showsms;

//~--- non-JDK imports --------------------------------------------------------

import android.app.Activity;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;

import android.graphics.Bitmap;

import android.net.Uri;

import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;

import android.preference.PreferenceManager;

import android.provider.Contacts;

import android.view.Display;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;

import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.bydavy.model.showsms.Person;
import com.bydavy.model.showsms.SSMessage;
import com.bydavy.util.showsms.Log;
import com.bydavy.util.showsms.NotificationEasier;

//~--- JDK imports ------------------------------------------------------------

import java.util.Timer;
import java.util.TimerTask;

/**
 * Preview activity
 *
 * @version        1.0, 09/06/21
 * @author         Davy L.
 */
public class PreviewActivity extends Activity {
    //~--- fields -------------------------------------------------------------

    /** Field description */
    private TimerTask MyTimerTask = null;

    /** Height and Weight of the photo */
    private final int PHOTO_HEIGHT_WIDTH = 80;

    /** Field description */
    private final double WIDTH_PROPORTION = 0.9;

    /** Connection for the binding */
    private ServiceConnection mConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder service) {
            serviceBinder = IPreviewService.Stub.asInterface(service);
        }
        public void onServiceDisconnected(ComponentName className) {
            serviceBinder = null;
        }
    };

    /** Field description */
    private SSMessage message = null;

    /** Service to bind */
    private IPreviewService serviceBinder = null;

    /** Timer for go to the new message or close the activity if no others messages */
    private Timer timer = new Timer();

    /** If unbind  service is necesary this is set to true. */
    private boolean unbind = true;

    /** Handler to process Activity view update */
    private PreviewViewUpdateHandler viewUpdateHandler = new PreviewViewUpdateHandler();

    /** Field description */
    private TextView bodyTV;

    /** Field description */
    private Button closeButton;

    /** Field description */
    private ImageButton contactIB;

    /** Field description */
    private ImageButton deleteIB;

    /** Field description */
    private long displayTime;

    /** Field description */
    private TextView hourTV;

    /** Field description */
    private TextView nameTV;

    /** Field description */
    private ImageView photoIV;

    /** Field description */
    private ImageButton quickeReplyIB;

    //~--- methods ------------------------------------------------------------

    /**
     * Method description
     *
     *
     * @return
     */
    public Object onRetainNonConfigurationInstance() {
        unbind = false;

        return null;
    }

    /**
     * Method description
     *
     *
     * @param savedInstanceState
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.v("PreviewActivity : onCreate()");

        // Binding
        bindService(new Intent(IPreviewService.class.getName()), mConnection, Context.BIND_AUTO_CREATE);

        // Disable title bar;
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.preview);

        // resize the application width
        LinearLayout mainLinearLayout = (LinearLayout) findViewById(R.id.PreviewMainLinearLayout);
        Display      d                = getWindowManager().getDefaultDisplay();
        int          width            = (int) (d.getWidth() * WIDTH_PROPORTION);

        mainLinearLayout.setMinimumWidth(width);

        // Set blur on background
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND, WindowManager.LayoutParams.FLAG_BLUR_BEHIND);

        // Layout View
        nameTV  = (TextView) findViewById(R.id.PreviewNameTV);
        photoIV = (ImageView) findViewById(R.id.PreviewPhotoSenderImageView);
        hourTV  = (TextView) findViewById(R.id.PreviewTVHour);
        bodyTV  = (TextView) findViewById(R.id.PreviewBodyTV);

        // Start the contact activity onClick
        photoIV.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                openContact();
            }
        });

        // Contact bouton
        contactIB = (ImageButton) findViewById(R.id.PreviewContactIB);
        contactIB.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                openContact();
            }
        });

        // delete bouton
        deleteIB = (ImageButton) findViewById(R.id.PreviewDeleteIB);
        deleteIB.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                viewUpdateHandler.DeleteMessage();
                viewUpdateHandler.NextMessageOrClose();
            }
        });

        // Quick Reply button
        quickeReplyIB = (ImageButton) findViewById(R.id.PreviewQuickReplyIB);
        quickeReplyIB.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                quickReply();
            }
        });

        // close bouton
        closeButton = (Button) findViewById(R.id.PreviewCloseButton);
        closeButton.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
				viewUpdateHandler.NextMessageOrClose();
            }
        });

        // if null, it the first execution of the activity
        if (savedInstanceState == null) {
            Log.v("PreviewActivity : First creation");
            message = SSMessage.constructFromBundle(getIntent().getExtras());
        } else {
            Log.v("PreviewActivity : Restore previous creation");
            message = SSMessage.constructFromBundle(savedInstanceState);
        }

        loadPreferences();
        populateViews(message);
    }

    //~--- set methods --------------------------------------------------------

    /**
     * Method description
     *
     *
     */
    private void setTimer() {

        // Action only if display time specified
        if (displayTime != -1) {
            MyTimerTask = new TimerTask() {
                @Override
                public void run() {
                    viewUpdateHandler.TimeOut();
                }
            };
            timer.schedule(MyTimerTask, displayTime);
        }
    }

    //~--- methods ------------------------------------------------------------

    /**
     * Construct the message with the intent
     * and give it to the service
     *
     * @param intent
     */
    public void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.v("PreviewActivity : onNewIntent()");
        viewUpdateHandler.NewMessageArrived(intent);
    }

    /**
     * Method description
     *
     */
    public void onStart() {
        super.onStart();
        Log.v("PreviewActivity : onStart()");
        setTimer();
    }

    /**
     * Method description
     *
     *
     * @param theMessage
     */
    private void populateViews(SSMessage theMessage) {
        Log.v("PreviewActivity : populateViews()");

        Person person        = theMessage.getPerson();
        Bitmap originalPhoto = person.getPhoto(getApplicationContext());
        Bitmap photo;

        photo = Bitmap.createScaledBitmap(originalPhoto, PHOTO_HEIGHT_WIDTH, PHOTO_HEIGHT_WIDTH, false);
        photoIV.setImageBitmap(photo);
        nameTV.setText(person.getNameOrPhoneNumber());
        hourTV.setText(theMessage.getHour(getApplicationContext()));
        bodyTV.setText(theMessage.getBody());
    }

    /**
     * Method description
     *
     */
    private void openContact() {
		/* Stop the close preview timer*/
		timer.purge();
        Intent contactIntent = new Intent();
        String phoneNumber   = message.getPerson().getPhoneNumber();

        contactIntent.setAction(Contacts.Intents.SHOW_OR_CREATE_CONTACT);
        contactIntent.addCategory(Intent.CATEGORY_DEFAULT);
        contactIntent.setData(Uri.fromParts("tel", phoneNumber, null));
        contactIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(contactIntent);
    }

    /**
     * Launch the default SMS messager for reply to the message
     * Not used for the moment
     */
    private void reply() {
		/* Stop the close preview timer*/
		timer.purge();
        Intent contactIntent = new Intent();
        long   threadId      = message.getThreadId();

        contactIntent.setAction(Intent.ACTION_VIEW);
        contactIntent.addCategory(Intent.CATEGORY_DEFAULT);
        contactIntent.setData(Uri.withAppendedPath(SSMessage.THREAD_ID_CONTENT_URI, String.valueOf(threadId)));
        contactIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(contactIntent);
    }

    /**
     * Launch show SMS Quick Reply feature
     *
     */
    private void quickReply() {
		/* Stop the close preview timer*/
		timer.purge();
        Intent QuickReplyIntent = new Intent(getApplicationContext(), QuickReplyActivity.class);

        QuickReplyIntent.putExtras(message.toBundle());
        QuickReplyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        startActivity(QuickReplyIntent);
    }

    /**
     * Method description
     *
     *
     *
     * @param item
     *
     * @return
     */

    /*
     * public boolean onCreateOptionsMenu(Menu menu) {
     *   super.onCreateOptionsMenu(menu);
     *   Log.v("PreviewActivity : onCreateOptionsMenu()");
     *
     *   MenuInflater inflater = getMenuInflater();
     *
     *   inflater.inflate(R.menu.preview_menu, menu);
     *
     *   return true;
     * }
     */

    /**
     * Method description
     * Not used for the moment
     *
     * @param item
     *
     * @return
     */
    public boolean onOptionsItemSelected(MenuItem item) {
        super.onOptionsItemSelected(item);
        Log.v("PreviewActivity : onOptionsItemSelected()");

        switch (item.getItemId()) {
        case R.id.PreviewMenuContact :
            openContact();

            return true;

        case R.id.PreviewMenuReply :
            reply();

            return true;
        }

        return false;
    }

    /**
     * When application loose the screen
     *
     */
    public void onStop() {
        super.onStop();
        Log.v("PreviewActivity : onStop()");
        timer.purge();
    }

    /**
     * Method description
     *
     */
    private void loadPreferences() {
        Log.v("PreviewActivity : loadPreferences()");

        SharedPreferences mySharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

        // loading display time from SharedPreferences
        String display_time_def = getString(R.preferences.display_time_def);

        displayTime = Long.valueOf(mySharedPreferences.getString(getString(R.preferences.display_time_key),
                display_time_def));
    }

    /**
     * Method description
     *
     *
     * @param outState
     */
    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        Log.v("PreviewActivity: onSaveInstanceState()");

        if (message != null) {
            Log.v("PreviewActivity: Saving state");
            outState.putAll(message.toBundle());
        }
    }

    /**
     * Method description
     *
     */
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.v("PreviewActivity: onDestroy()");

        if (unbind && (mConnection != null)) {
            unbindService(mConnection);
        }

        timer.cancel();
    }

    //~--- inner classes ------------------------------------------------------

    /**
     * Handler that will process all view change
     *
     * @version        1.0, 09/11/08
     * @author         Davy L.
     */
    class PreviewViewUpdateHandler extends Handler {

	/** type for message posted in the handler */
        private final int NEXT_OR_CLOSE = 1;
	
        /** type for message posted in the handler */
        private final int NEW_MESSAGE_ARRIVED = 2;

        /** type for message posted in the handler */
        private final int TIME_OUT = 3;
		
		private final int DELETE_MESSAGE = 5;
		
		public void NextMessageOrClose()
		{
			sendEmptyMessage(NEXT_OR_CLOSE);
		}
		
		public void DeleteMessage()
		{
			sendEmptyMessage(DELETE_MESSAGE);
		}
		
        /**
         * Called when a new message arrived
         *
         *
         * @param intent
         */
        public void NewMessageArrived(Intent intent) {
            Message msg = new Message();

            msg.what = NEW_MESSAGE_ARRIVED;
            msg.obj  = intent;
            sendMessage(msg);
        }

        /**
         * Called when timer is elapsed
         *
         */
        public void TimeOut() {
            //sendEmptyMessage(TIME_OUT);
        	finish();
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
			/*  Delete the current message and try to close the preview Activity if there are no more SMS*/
			case DELETE_MESSAGE:
				message.delete(getApplicationContext());
				NextMessageOrClose();
				break;
			/* Time elapsed , try to close the preview Activity if there are no more SMS*/
            case TIME_OUT :
                NextMessageOrClose();
                break;
			/* Transmit to the service the new SMS received */
            case NEW_MESSAGE_ARRIVED :
                if (serviceBinder != null) {
                    try {

                        // Archive the message
                        serviceBinder.addMessageFromIntent((Intent) msg.obj);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }

				/*  Toast Message when SMS received */
                Toast newMessageReveivedToast = Toast.makeText(getApplicationContext(),
                                                    getString(R.string.preview_new_message_toast), Toast.LENGTH_SHORT);

                newMessageReveivedToast.show();
				/* Close button becom a next button */
                closeButton.setText(getString(R.string.preview_next));
                break;
				case NEXT_OR_CLOSE:
					Log.d("PreviewActivity : close()");
			        timer.purge();
			        //Mark as read the message
			        message.markAsRead(getApplicationContext());
			        
			        //"Delete" message
			        if (message != null) {
			            message = null;
			        }

			        try {
			            message = serviceBinder.getMessage();

			            if (message == null) {
			                Log.d("PreviewActivity : finish()");
			                //cancel Notification
					        NotificationEasier.cancelNewMessage();
			                finish();
			            } else {
			                populateViews(message);

			                int nb = serviceBinder.messageCount();

			                if (nb == 0) {
			                    closeButton.setText(getString(R.string.preview_close));
			                }

			                setTimer();
			            }
			        } catch (RemoteException e) {
			            e.printStackTrace();
			            Log.e("ERROR with getMessage from the serviceBinder");
			         	
			            finish();
			        }
				break;
            // Used when msg is a runnable
            default :
                super.handleMessage(msg);
            }
        }
    }


    ;
}
